open Unix

open Common

exception Iconv_open_failed
exception Iconv_failed

exception Get_pass_failed

let print_normal_msg msg = 
  if not !quiet then Printf.printf "%s" msg;
  flush_all ()

let print_error_msg msg = 
  if not !quiet then Printf.printf "[EE] %s" msg;
  flush_all ()

let print_warning_msg msg = 
  if not !quiet then Printf.printf "[WW] %s" msg;
  flush_all ()

let print_debug_msg msg = 
  if (not !quiet)&&(!debug) then Printf.printf "[DD] %s" msg;
  flush_all ()

let remove_trailing_cr msg =
  let len = String.length msg in
  if len > 0 && msg.[len-1]='\r' then String.sub msg 0 (len-1) else msg

let remove_trailing_lf msg =
  let len = String.length msg in
  if len > 0 && msg.[len-1]='\n' then String.sub msg 0 (len-1) else msg

let remove_trailing_cr_lf msg =
  let len = String.length msg in
  if len=0 then 
    msg
  else
    (
     let cur_pos = ref (len-1) in
     let loop_cond = ref (!cur_pos>=0) in
     while !loop_cond do
       if msg.[!cur_pos]='\r' || msg.[!cur_pos]='\n' then
         (
          decr cur_pos; loop_cond := (!cur_pos>=0)
         )
       else
         loop_cond := false;
     done;
     if !cur_pos<0 then
       ""
     else
       String.sub msg 0 (!cur_pos+1)
    )

let remove_heading_blank msg =
  let msg_len = String.length msg in
  let pos = ref 0 in
  let noblank = ref false in
  while (!pos<msg_len)&&(not !noblank) do
    let c = msg.[!pos] in
    if c<>' '&&c<>'\t' then
      noblank := true;
    incr pos
  done;
  if !noblank then
    String.sub msg (!pos-1) (msg_len-(!pos)+1)
  else
    msg
      
let break_into_lines msg =
  let lines = ref [] in
  let start_pos = ref 0 in
  for index = 0 to (String.length msg)-1 do
    if msg.[index]='\n' then 
      (lines := (String.sub msg !start_pos (index-(!start_pos)+1))::!lines;
       start_pos := index+1)
  done;
  List.rev !lines
    
let getc fd =
  let buf = String.create 1 in
  let size = read fd buf 0 1 in
  if size<>0 then
    String.get buf 0
  else
    raise End_of_file

external iconv_line_ml : string -> string -> string -> string =
  "iconv_line_c"

let _ = Callback.register_exception "Iconv_open_failed" (Iconv_open_failed)
let _ =Callback.register_exception "Iconv_failed" (Iconv_failed)

let iconv_line line_str fromcode tocode =
  let in_line = line_str 
  in
  try
    iconv_line_ml in_line fromcode tocode
  with
  | _ -> in_line

external get_pass_ml : unit -> string = "get_pass_c"

let _ = Callback.register_exception "Get_pass_failed" (Get_pass_failed)

let get_pass () =
  get_pass_ml ()
